﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DataModelWF
{
    public class ConnPool
    {
        private Stack<SqlConnection> pool;
        private const int POOL_MAX_SIZE = 20;
        private int current_Size = 0; 
        private string ConnString = "";//连接字符串  

        public void setConnString(string connstr)
        {
            this.ConnString = connstr;
        }

        private static ConnPool connPool;

        private ConnPool()
        {
            if (pool == null)
            {
                pool = new Stack<SqlConnection>();
            }
        }

        private static Mutex mutex = new Mutex();
        public static ConnPool getInstance()
        {
            mutex.WaitOne();
            if (connPool == null)
            {
                connPool = new ConnPool();
            }
            mutex.ReleaseMutex();
            return connPool;
        }

        public SqlConnection getConnection()
        {
            SqlConnection conn;
            lock (this)
            {
                if (pool.Count == 0)
                {
                    if (current_Size < POOL_MAX_SIZE)
                    {
                        conn = createConnection();
                        current_Size++;

                        pool.Push(conn);
                    }
                    else
                    {
                        try
                        {
                            Monitor.Wait(this);
                        }
                        catch (Exception e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }
                }
                conn = (SqlConnection)pool.Pop();
            }
            return conn;
        }

        private string GetConnString()
        {
            if (string.IsNullOrEmpty(ConnString))
            {
                throw new Exception("连接字符串为空");
            }
            return ConnString;
        }

        public void releaseConnection(SqlConnection conn)
        {
            lock (this)
            {
                pool.Push(conn);
                Monitor.Pulse(this);
            }
        }

        private SqlConnection createConnection()
        {
            lock (this)
            {
                SqlConnection newConn = new SqlConnection(GetConnString());
                newConn.Open();
                return newConn;
            }
        }
    }
}
